package com.vn.toaa.karaoke.ui;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.regex.Pattern;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.startapp.android.publish.StartAppAd.AdMode;
import com.vn.toaa.karaoke.database.DatabaseManager;
import com.vn.toaa.karaoke.database.SongModel;
import com.vn.toaa.karaoke.ui.ClearableEditText.IAfterTextChangedListener;
import com.vn.toaa.karaoke.ui.Constant.SongCollection;
import com.vn.toaa.karaoke.ui.FavoriteAdapter.Item;
import com.vn.toaa.karaoke.ui.FavoriteAdapter.Row;
import com.vn.toaa.karaoke.ui.FavoriteAdapter.Section;
import com.vn.toaa.karaoke.utils.CommonUtils;
import com.vn.toaa.karaokecodelist.R;

public class FavoriteActivity extends BaseAdsActivity implements IAfterTextChangedListener, IDeleteFavoriteListener {
	
	private ListView mLvSong;
	private ClearableEditText mEdSearch;
	private TextView mTvNotification;
	private List<Integer> mFavoriteList;
    private FavoriteAdapter adapter = new FavoriteAdapter();
    private List<Object[]> alphabet = new ArrayList<Object[]>();
    private HashMap<String, Integer> sections = new HashMap<String, Integer>();
	private ArrayList<Row> mRows;
	private List<SongModel> mSongModels;
	private SearchKeywordAsync mSearchKeywordAsync;
	private Dialog mDialog;
	private Handler mHandler = new Handler();
	private Random mRandom = new Random();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.favorite_activity);
		
		adapter.setDeleteFavoriteListener(this);
		mLvSong = (ListView) findViewById(R.id.listivew_song);
		mEdSearch = (ClearableEditText) findViewById(R.id.edittext_search);
		mTvNotification = (TextView) findViewById(R.id.textview_notification);
		final Button btBack = (Button) findViewById(R.id.button_back);
		final Button btRefresh = (Button) findViewById(R.id.button_refresh);
		final Button btSearch = (Button) findViewById(R.id.button_search);
		final Button btStoreOnine = (Button) findViewById(R.id.button_store_online);
		final Button btDownload = (Button) findViewById(R.id.button_donwload);
		final TextView tvTitle = (TextView) findViewById(R.id.textview_title);
		mEdSearch.setHintText("Tìm kiếm bài hát yêu thích");
		mEdSearch.setIAfterTextChangedListener(this);
		btBack.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				finish();
			}
		});
		btRefresh.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				mEdSearch.setText("");
				new LoadingDataAsync().execute();
			}
		});
		btSearch.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if (mEdSearch.isShown()) {
					mEdSearch.setText("");
					mEdSearch.setVisibility(View.GONE);
					tvTitle.setVisibility(View.VISIBLE);
					btBack.setVisibility(View.VISIBLE);
					InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
					imm.hideSoftInputFromWindow(mEdSearch.getWindowToken(), 0);
				} else {
					mEdSearch.setVisibility(View.VISIBLE);
					mEdSearch.requestFocus();
					tvTitle.setVisibility(View.GONE);
					btBack.setVisibility(View.GONE);
					InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
					imm.showSoftInput(mEdSearch, 0);
				}
			}
		});
		
		mLvSong.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(final AdapterView<?> parent, View view, final int position, long id) {
				runOnUiThread(new Runnable() {
					public void run() {
						if (parent.getAdapter().getItem(position) instanceof Item) {
							Intent intent = new Intent(FavoriteActivity.this, DetailActivity.class);
							intent.putExtra(Constant.EXTRA_SONG_ID, ((Item) parent.getAdapter().getItem(position)).mSongId);
							intent.putExtra(Constant.EXTRA_SONG_COLLECTION, ((Item) parent.getAdapter().getItem(position)).mCollection);
							startActivity(intent);
						}
					}
				});
			}
		});
		btStoreOnine.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				displayDialogById(0);
			}
		});
		btDownload.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				displayDialogById(1);
			}
		});
		new LoadingDataAsync().execute();
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		mEdSearch.setIAfterTextChangedListener(this);
	}
	
	private void initData() {
		mFavoriteList = DatabaseManager.getInstance().selectAllFavoriteSong();
		mSongModels = new ArrayList<SongModel>();
		if (mFavoriteList != null) {
			int collectionNumber = SongCollection.FIVE_NUMBER.ordinal();
			for (Integer songId : mFavoriteList) {
				SongModel songModel = DatabaseManager.getInstance().selectSongById(songId, SongCollection.FIVE_NUMBER);
				collectionNumber = SongCollection.FIVE_NUMBER.ordinal();
				if (songModel == null) {
					songModel = DatabaseManager.getInstance().selectSongById(songId, SongCollection.SIX_NUMBER);
					collectionNumber = SongCollection.SIX_NUMBER.ordinal();
				}
				if (songModel != null) {
					songModel.setCollection(collectionNumber);
					mSongModels.add(songModel);
				}
			}
			ValueContainer.getInstance().setSongModelsInFavorite(mSongModels);
		}
		initViews(true);
	}
	
	/**
     * Initialize ListView and Navigation view
     */
	private void initViews(boolean shouldSort) {
        if (mSongModels == null) {
			return;
		}
        if (shouldSort) {
        	Collections.sort(mSongModels);
		}
		alphabet = new ArrayList<Object[]>();
        mRows = new ArrayList<Row>();
        int start = 0;
        int end = 0;
        String previousLetter = null;
        Object[] tmpIndexItem = null;
        Pattern numberPattern = Pattern.compile("[0-9]");

        for (SongModel songModel : mSongModels) {
            String firstLetter = songModel.getTitleAbbr().substring(0, 1).toUpperCase();
            if (Arrays.asList(Constant.GROUP_A).contains(firstLetter)) {
				firstLetter = "A";
			} else if (Arrays.asList(Constant.GROUP_D).contains(firstLetter)) {
				firstLetter = "D";
			} else if (Arrays.asList(Constant.GROUP_E).contains(firstLetter)) {
				firstLetter = "E";
			} else if (Arrays.asList(Constant.GROUP_O).contains(firstLetter)) {
				firstLetter = "O";
			} else if (Arrays.asList(Constant.GROUP_U).contains(firstLetter)) {
				firstLetter = "U";
			}

            // Group numbers together in the scroller
            if (numberPattern.matcher(firstLetter).matches()) {
                firstLetter = "#";
            }

            // If we've changed to a new letter, add the previous letter to the alphabet scroller
            if (previousLetter != null && !firstLetter.equals(previousLetter)) {
                end = mRows.size() - 1;
                tmpIndexItem = new Object[3];
                tmpIndexItem[0] = previousLetter.toUpperCase(Locale.UK);
                tmpIndexItem[1] = start;
                tmpIndexItem[2] = end;
                alphabet.add(tmpIndexItem);

                start = end + 1;
            }

            // Check if we need to add a header row
            if (!firstLetter.equals(previousLetter)) {
                mRows.add(new Section(firstLetter));
                sections.put(firstLetter, start);
            }

            // Add the country to the list
			mRows.add(new Item(songModel.getSongId(), songModel.getCollection(), songModel.getTitle(), songModel.getLyric(), false));
            previousLetter = firstLetter;
        }

        if (previousLetter != null) {
            // Save the last letter
            tmpIndexItem = new Object[3];
            tmpIndexItem[0] = previousLetter.toUpperCase(Locale.UK);
            tmpIndexItem[1] = start;
            tmpIndexItem[2] = mRows.size() - 1;
            alphabet.add(tmpIndexItem);
        }
	}
	
	/**
	 * Refresh ListView and Navigation view on UI thread
	 */
	private void refreshListView() {
		runOnUiThread(new Runnable() {
			public void run() {
				adapter.setRows(mRows);
				mLvSong.setAdapter(adapter);
				mLvSong.scrollTo(0, 0);
				if (mSongModels == null || mSongModels.size() <= 0) {
					mLvSong.setVisibility(View.GONE);
					mTvNotification.setVisibility(View.VISIBLE);
				} else {
					mLvSong.setVisibility(View.VISIBLE);
					mTvNotification.setVisibility(View.GONE);
				}
			}
		});
	}
	
	class LoadingDataAsync extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... params) {
			initData();
			return null;
		}
		
		@Override
		protected void onPostExecute(Void result) {
			if (isCancelled()) {
				return;
			}
			refreshListView();
		}
	}
	
	class SearchKeywordAsync extends AsyncTask<String, Void, Void> {

		@Override
		protected Void doInBackground(String... params) {
			if (isCancelled()) {
				return null;
			}
			String keyword = params[0].toLowerCase();
			if (ValueContainer.getInstance().getSongModelsInFavorite() != null) {
				mSongModels = new ArrayList<>();
				final List<SongModel> highPriorityList = new ArrayList<SongModel>();
				final List<SongModel> lowPriorityList = new ArrayList<SongModel>();
				for (int i = ValueContainer.getInstance().getSongModelsInFavorite().size() - 1; i >= 0; i--) {
					if (isCancelled()) {
						return null;
					}
					final SongModel songModel = ValueContainer.getInstance().getSongModelsInFavorite().get(i);
					final String songId = String.valueOf(songModel.getSongId()).toLowerCase();
					final String songTitle = songModel.getTitle().toLowerCase();
					final String songTitleSearch = songModel.getTitleSearch().toLowerCase();
					final String songLyric = songModel.getLyric().toLowerCase();
					final String songLyricSearch = songModel.getLyricSearch().toLowerCase();
					final String songAuthor = songModel.getAuthor().toLowerCase();
					final String songAuthorSearch = songModel.getAuthorSearch().toLowerCase();
					if (songId.contains(keyword) || songTitle.contains(keyword) || songTitleSearch.contains(keyword)) {
						highPriorityList.add(songModel);
					} else if (songLyric.contains(keyword) || songLyricSearch.contains(keyword)
							|| songAuthor.contains(keyword) || songAuthorSearch.contains(keyword)) {
						lowPriorityList.add(songModel);
					}
				}
				mSongModels.addAll(highPriorityList);
				mSongModels.addAll(lowPriorityList);
				initViews(false);
			}
			return null;
		}
		
		@Override
		protected void onPostExecute(Void result) {
			if (isCancelled()) {
				return;
			}
			refreshListView();
		}
		
	}
	
	private void displayDialogById(final int id) {
		mDialog = new Dialog(this);
		mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
		mDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
		final View rootView = LayoutInflater.from(this).inflate(R.layout.favorite_dialog, null);
		final TextView tvTitle = (TextView) rootView.findViewById(R.id.textview_sync_title);
		final EditText edName = (EditText) rootView.findViewById(R.id.edittext_name);
		final EditText edEmail = (EditText) rootView.findViewById(R.id.edittext_email);
		final Button btOK = (Button) rootView.findViewById(R.id.button_ok);
		final Button btCancel = (Button) rootView.findViewById(R.id.button_cancel);
		final TextView tvDescription = (TextView) rootView.findViewById(R.id.textview_description);
		
		SharedPreferences preferences = getSharedPreferences(getPackageName(), MODE_PRIVATE);
		edName.setText(preferences.getString(Constant.PREF_USER_NAME, ""));
		edEmail.setText(preferences.getString(Constant.PREF_USER_EMAIL, ""));
		if (id == 0) {
			tvTitle.setText("LƯU DANH SÁCH BÀI HÁT");
			tvDescription.setText(getString(R.string.message_store));
			btOK.setText("Lưu");
		} else {
			tvTitle.setText("TẢI DANH SÁCH BÀI HÁT");
			tvDescription.setText(getString(R.string.message_download));
			btOK.setText("Tải");
		}
		btOK.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if (TextUtils.isEmpty(edName.getText().toString())) {
					edName.setError("Không để trống");
				}
				if (TextUtils.isEmpty(edEmail.getText().toString())) {
					edEmail.setError("Không để trống");
				}
				if (!TextUtils.isEmpty(edName.getText().toString()) && !TextUtils.isEmpty(edEmail.getText().toString())) {
					if (!CommonUtils.isEmailAddressValid(edEmail.getText().toString())) {
						edEmail.setError("Email không đúng");
						return;
					}
					SharedPreferences preferences = getSharedPreferences(getPackageName(), MODE_PRIVATE);
					preferences.edit().putString(Constant.PREF_USER_NAME, edName.getText().toString()).commit();
					preferences.edit().putString(Constant.PREF_USER_EMAIL, edEmail.getText().toString()).commit();
					
					if (id == 0) {
						if (TextUtils.isEmpty(convertSongListToString())) {
							Toast.makeText(getApplicationContext(), "Danh sách yêu thích trên máy của bạn đang trống.", Toast.LENGTH_LONG).show();
						} else {
							new UploadAsync().execute(edName.getText().toString(), edEmail.getText().toString());
						}
					} else {
						new DownloadAsync().execute(edName.getText().toString(), edEmail.getText().toString());
					}
				}
			}
		});
		btCancel.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				mDialog.dismiss();
			}
		});
		
		DisplayMetrics displaymetrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
		int width = displaymetrics.widthPixels;
		final int defaultWidth = (int) (width * 0.9f);
		mDialog.setContentView(rootView);
		mDialog.getWindow().setLayout(defaultWidth, LayoutParams.WRAP_CONTENT);
		mDialog.show();
	}
	
	class UploadAsync extends AsyncTask<String, Void, Boolean> {
		
		private ProgressDialog mPbLoading;
		
		@Override
		protected void onPreExecute() {
			mPbLoading = ProgressDialog.show(FavoriteActivity.this, null, "Loading");
		}

		@Override
		protected Boolean doInBackground(String... params) {
			final String name = params[0];
			final String email = params[1];
			HttpClient httpclient = new DefaultHttpClient();
		    HttpPost httppost = new HttpPost("http://androidtoaa.site50.net/android/karaoke_dictionary/upload_favorite.php");
		    
		    try {
		        // Add your data
		        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		        nameValuePairs.add(new BasicNameValuePair("name", name));
		        nameValuePairs.add(new BasicNameValuePair("email", email));
		        nameValuePairs.add(new BasicNameValuePair("favorite", convertSongListToString()));
		        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

		        // Execute HTTP Post Request
		        HttpResponse response = httpclient.execute(httppost);
		        if (response != null) {
					final String result = IOUtils.toString(response.getEntity().getContent());
					System.out.println("xxx " + result);
					try {
						JSONObject jsonObject = new JSONObject(result);
						return jsonObject.getBoolean("status");
					} catch (JSONException e) {
						e.printStackTrace();
						return false;
					}
				}

		    } catch (ClientProtocolException e) {
		    	e.printStackTrace();
		    	return false;
		    } catch (IOException e) {
		    	e.printStackTrace();
		    	return false;
		    }
			return false;
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			if (!isFinishing()) {
				mPbLoading.dismiss();
			}
			if (result != null && result) {
				Toast.makeText(getApplicationContext(), "Lưu online thành công.", Toast.LENGTH_LONG).show();
				if (mDialog != null && mDialog.isShowing()) {
					mDialog.dismiss();
				}
				if (mRandom.nextBoolean()) {
					mHandler.postDelayed(new Runnable() {
						public void run() {
							showInterstitialAd(AdMode.AUTOMATIC);
						}
					}, 500);
				}
			} else {
				Toast.makeText(getApplicationContext(), "Lưu online thất bại, vui lòng thử lại.", Toast.LENGTH_LONG).show();
			}
		}
	}
	
	class DownloadAsync extends AsyncTask<String, Void, String> {
		
		private ProgressDialog mPbLoading;
		
		@Override
		protected void onPreExecute() {
			mPbLoading = ProgressDialog.show(FavoriteActivity.this, null, "Loading");
		}

		@Override
		protected String doInBackground(String... params) {
			final String name = params[0];
			final String email = params[1];
			HttpClient httpclient = new DefaultHttpClient();
		    HttpPost httppost = new HttpPost("http://androidtoaa.site50.net/android/karaoke_dictionary/download_favorite.php");
		    
		    try {
		        // Add your data
		        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		        nameValuePairs.add(new BasicNameValuePair("name", name));
		        nameValuePairs.add(new BasicNameValuePair("email", email));
		        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

		        // Execute HTTP Post Request
		        HttpResponse response = httpclient.execute(httppost);
		        if (response != null) {
					final String result = IOUtils.toString(response.getEntity().getContent());
					System.out.println("xxx " + result);
					try {
						JSONObject jsonObject = new JSONObject(result);
						return jsonObject.getString("favorite");
					} catch (JSONException e) {
						e.printStackTrace();
						return null;
					}
				}
		    } catch (ClientProtocolException e) {
		    	e.printStackTrace();
		    	return null;
		    } catch (IOException e) {
		    	e.printStackTrace();
		    	return null;
		    }
			return null;
		}
		
		@Override
		protected void onPostExecute(String result) {
			if (!isFinishing()) {
				mPbLoading.dismiss();
			}
			if (result != null) {
				if ("".equals(result)) {
					Toast.makeText(getApplicationContext(), "Danh sách yêu thích online của bạn đang trống.", Toast.LENGTH_LONG).show();
				} else {
					Toast.makeText(getApplicationContext(), "Tải danh sách thành công.", Toast.LENGTH_LONG).show();
					if (mDialog != null && mDialog.isShowing()) {
						mDialog.dismiss();
					}
					final String[] songCodes = convertSongStringToList(result);
					for (int i = 0; i < songCodes.length; i++) {
						try {
							DatabaseManager.getInstance().insertFavoriteSong(Integer.parseInt(songCodes[i]));
						} catch (NumberFormatException e) {
							e.printStackTrace();
						}
					}
					new LoadingDataAsync().execute();
					if (mRandom.nextBoolean()) {
						mHandler.postDelayed(new Runnable() {
							public void run() {
								showInterstitialAd(AdMode.AUTOMATIC);
							}
						}, 500);
					}
				}
			} else {
				Toast.makeText(getApplicationContext(), "Tải danh sách thất bại, vui lòng thử lại.", Toast.LENGTH_LONG).show();
			}
		}
	}
	
	private String convertSongListToString() {
		StringBuilder stringBuilder = new StringBuilder();
		final List<Integer> favoriteSongIdList = DatabaseManager.getInstance().selectAllFavoriteSong();
		if (favoriteSongIdList != null) {
			for (Integer songId : favoriteSongIdList) {
				stringBuilder.append(songId);
				stringBuilder.append(",");
			}
			if (stringBuilder.length() > 0) {
				stringBuilder.deleteCharAt(stringBuilder.length() - 1);
			}
		}
		return stringBuilder.toString();
	}
	
	private String[] convertSongStringToList(String songCodes) {
		if (TextUtils.isEmpty(songCodes)) {
			return new String[0];
		}
		return songCodes.split(",");
	}
	
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
	}

	@Override
	public void onAfterTextChanged() {
		if (mSearchKeywordAsync != null) {
			mSearchKeywordAsync.cancel(true);
		}
		mSearchKeywordAsync = new SearchKeywordAsync();
		mSearchKeywordAsync.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, mEdSearch.getText().toString());
	}

	@Override
	public void onFavoriteDeleted() {
		new LoadingDataAsync().execute();
	}
}
